import { asyncRoutes, constantRoutes } from '@/router'
import { getAuthMenu, getRouters } from '@/api/common/login'
import Layout from '@/layout/index2'
import { deepClone } from '@/utils'
import { superRoutes } from '@/router/default'
import store from '@/store'
/**
 * 后台查询的菜单数据拼装成路由格式的数据
 * @param routes
 * @param menuList 后台得到集合
 */
export function generaMenu(routes, menuList) {
  let temp = []
  for (let i = 0; i < menuList.length; i++) {
    if (menuList[i].childNodes && menuList[i].childNodes.length >= 1) {
      temp = temp.concat(menuList[i].childNodes)
    } else {
      temp = []
    }
    if (menuList[i].menuPath && /\S/.test(menuList[i].menuPath)) {
      const menu = {
        id: menuList[i].menuId,
        path: menuList[i].menuPath === '#' ? menuList[i].menuId + '_key' : menuList[i].menuPath,
        component: menuList[i].component === '#' ? Layout : resolve => require([`@/views${menuList[i].component}`], resolve),
        // component: menuList[i].component === '#' ? Layout : () => import(`@/views${menuList[i].component}`),
        name: menuList[i].menuName,
        meta: {
          title: menuList[i].title,
          icon: menuList[i].menuIcon,
          auth: menuList[i].permission === '#' ? null : ['' + menuList[i].permission + '']
        }
      }
      if (temp.length >= 1) {
        menu.alwaysShow = true
        const child = []
        generaMenu(child, temp)
        menu.children = child
        temp = []
      }
      routes.push(menu)
    }
  }
}
/**
 * 判断权限
 * @param authList
 * @param route
 */
function hasAuthorization(authList, route) {
  if (route.meta && route.meta.auth) { // 当前路由有meta 并且 meta下有auth
    return authList.some(auth => { //   .some ：数组中的元素是否满足指定条件
      return route.meta.auth.some(routeAuth => {
        return routeAuth === auth
      })
    })
  } else { // 当前路由无meta 或 auth（1：无需鉴权；2：有children）
    return true
  }
}
// 路由与用户权限集合匹配的方法
export function filterAsyncRoutes(routes, authList) {
  const res = []
  routes.forEach(route => {
    const tmp = route
    if (hasAuthorization(authList, tmp)) { // 先判断当前路由是否有权限
      if (tmp.children) { // tmp下有children时，用children递归
        tmp.children = filterAsyncRoutes(tmp.children, authList)
      }
      // children等于undefined：当前路由没有下级路由，且有访问权限
      // children.length > 0：当前路由有下级路由，且下级路由有访问权限，则把当前路由添加到返回值
      if (typeof (tmp.children) === 'undefined' || tmp.children.length > 0) {
        res.push(tmp)
      }
    }
  })
  return res
}

const state = {
  allRoutes: [], // 侧边栏生成前，保存一份完整的路由信息
  routes: [],
  addRoutes: [],
  authList: [],
  activeMenu: ''
}
const getters = {
  hasAuthorizations: (state, getters, rootState) => authorization => {
    // 如果用户名为superadmin，显示所有按钮
    if (rootState.user.name === 'superadmin') {
      return true
    }
    return state.authList.some(auth => {
      return auth === authorization
    })
  }
}
const mutations = {
  SET_activeMenu: (state, activeMenu) => {
    state.activeMenu = activeMenu
  },
  SET_allRoutes: (state, allRoutes) => {
    state.allRoutes = allRoutes
  },
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },
  SET_AUTH: (state, authList) => {
    state.authList = authList
  },
  CLEAR_ROUTES: (state) => {
    state.allRoutes = []
    state.routes = []
    state.addRoutes = []
    state.authList = []
  }
}

const actions = {
  generateRoutes({ state, commit, rootState }, { authList, userName, userId }) {
    return new Promise(resolve => {
      // 先查询后台并返回左侧菜单数据并把数据添加到路由
      getAuthMenu({ uId: userId }).then(response => {
        // 获取router下index.js中的asyncRoutes
        const tempAsyncRoutes = Object.assign([], asyncRoutes)
        // 动态循环路由信息
        generaMenu(tempAsyncRoutes, response.menus)
        let allRoutes = deepClone(state.allRoutes) // 深拷贝一份 asyncRoutes，不影响vuex中保存的 asyncRoutes
        // 如果 allRoutes 长度为0 说明是刷新了页面，导致 vuex 被清空
        if (allRoutes.length === 0) {
          // 直接使用 asyncRoutes
          allRoutes = tempAsyncRoutes
        }
        // 先在vuex里存放一份完整的路由信息，深拷贝，vuex里保存的asyncRoutes 与此处的asyncRoutes无关，此处的asyncRoutes会改变
        commit('SET_allRoutes', deepClone(allRoutes))
        let accessedRoutes = []
        if (userName === 'superadmin') {
          accessedRoutes = allRoutes || [] // 全部显示
        } else {
          accessedRoutes = filterAsyncRoutes(allRoutes, authList)
        }
        commit('SET_ROUTES', accessedRoutes)
        commit('SET_AUTH', authList)
        resolve(accessedRoutes)
      }).catch(error => {
        // console.log(error)
      })
    })
  },
  clearRoutes({ commit }) {
    commit('CLEAR_ROUTES')
  },
  setAllRoutes({ commit }, allRoutes) {
    commit('SET_allRoutes', allRoutes)
  },
  setActiveMenu({ commit }, activeMenu) {
    commit('SET_activeMenu', activeMenu)
  },
  getRouters({ commit }) {
    return new Promise(resolve => {
      const loginUserName = store.getters.loginUserName
      if (loginUserName === 'superadmin') { // 如果是超级管理员
        const routers = superRoutes
        routers.push({ path: '*', redirect: '/404', hidden: true })
        commit('SET_ROUTES', routers)
        commit('SET_allRoutes', routers)
        resolve(routers)
      } else {
        getRouters().then(res => {
          commit('SET_allRoutes', res.data)
          const rdata = JSON.parse(JSON.stringify(res.data))
          const rewriteRoutes = filterAsyncRouter(rdata, false, true)
          // 给每个一级菜单加一个 index 子菜单
          const routers = addIndexRouter(rewriteRoutes)
          routers.push({ path: '*', redirect: '/404', hidden: true })
          // console.log('routers', routers)
          commit('SET_ROUTES', routers)
          resolve(routers)
        })
      }
    }).finally(() => {
      store.state.app.loadingFull = false
    })
  }
}
function addIndexRouter(routers) {
  routers.forEach(item => {
    const newItem = {
      path: '',
      component: resolve => require([`@/views${item.path}`], resolve),
      name: item.name + '-Index',
      meta: { title: item.meta.title, icon: item.meta.icon, menuId: item.meta.menuId }
    }
    if (!item.children) {
      item.children = []
    }
    item.children.push(newItem)
  })
  return routers
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
  return asyncRouterMap.filter(route => {
    if (type && route.children) {
      route.children = filterChildren(route.children)
    }
    if (route.component) {
      // Layout 组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else {
        route.component = loadView(route.component)
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, route, type)
    } else {
      delete route['children']
      delete route['redirect']
    }
    return true
  })
}

function filterChildren(childrenMap, lastRouter = false) {
  var children = []
  childrenMap.forEach((el, index) => {
    if (el.children && el.children.length) {
      if (el.component === 'ParentView') {
        el.children.forEach(c => {
          c.path = el.path + '/' + c.path
          if (c.children && c.children.length) {
            children = children.concat(filterChildren(c.children, c))
            return
          }
          children.push(c)
        })
        return
      }
    }
    if (lastRouter) {
      el.path = lastRouter.path + '/' + el.path
    }
    children = children.concat(el)
  })
  return children
}

export const loadView = (view) => { // 路由懒加载
  return (resolve) => require([`@/views/${view}`], resolve)
}
export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
